package cn.b.sky.mes.em.service.impl;

import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import cn.b.sky.mes.em.enums.MaintainTaskStatus;
import cn.b.sky.mes.em.enums.StrategyType;
import cn.b.sky.mes.em.model.MaintainConfig;
import cn.b.sky.mes.em.model.MaintainConfigAttach;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import cn.b.sky.mes.em.dao.MaintainConfigDao;
import cn.b.sky.mes.em.model.condition.MaintainConfigCondition;
import cn.b.sky.mes.em.service.MaintainConfigService;
import cn.b.sky.mes.em.service.MaintainTaskService;
import cn.b.sky.common.model.BatchJobReport;
import cn.b.sky.common.utils.DatabaseUtils;
import cn.b.sky.common.utils.FTPUtils;
import cn.b.sky.common.utils.SkyFileUtils;
import cn.b.sky.common.utils.SpringBeanUtil;
import cn.b.sky.i18n.utils.LocaleResourceBundle;
import cn.b.sky.user.SecurityContextUtil;
import cn.b.sky.user.model.Attachment;
import cn.b.sky.user.service.AttachmentService;

@Service("maintainConfigService")
public class MaintainConfigServiceImpl implements MaintainConfigService {
  private static final Logger LOGGER = LoggerFactory.getLogger(MaintainConfigServiceImpl.class);

  @Resource
  MaintainConfigDao maintainConfigDao;

  @Resource
  AttachmentService attachmentService;

  @Resource
  MaintainTaskService maintainTaskService;

  @Override
  public List<MaintainConfig> selectMaintainConfigByCondition(MaintainConfigCondition maintainConfigCondition) {
    return maintainConfigDao.selectMaintainConfigByCondition(maintainConfigCondition);
  }

  @Override
  public int selectMaintainConfigCount(MaintainConfigCondition maintainConfigCondition) {
    return maintainConfigDao.selectMaintainConfigCount(maintainConfigCondition);
  }

  @Override
  public MaintainConfig selectMaintainConfigByCode(String siteCode, String equipmentCode, String strategyCode) {
    return maintainConfigDao.selectMaintainConfigByCode(siteCode, equipmentCode, strategyCode);
  }

  @Override
  public List<MaintainConfigAttach> selectMaintainConfigAttachList(String siteCode, String equipmentCode,
                                                                   String strategyCode) {
    return maintainConfigDao.selectMaintainConfigAttachList(siteCode, equipmentCode, strategyCode);
  }

  @Override
  public void insertMaintainConfig(MaintainConfig maintainConfig) {
    if (maintainConfig.getPrevMaintainDate() != null) {
      Calendar cld = Calendar.getInstance();
      cld.setTime(maintainConfig.getPrevMaintainDate());
      maintainConfig.setMaintainDayOfMonth(cld.get(Calendar.DAY_OF_MONTH));
    }
    maintainConfigDao.insertMaintainConfig(maintainConfig);

  }

  @Override
  public void updateMaintainConfig(MaintainConfig maintainConfig) {
    //关键元素发生更改则删除未执行的维护任务
    MaintainConfig c = maintainConfigDao.selectMaintainConfigByCode(maintainConfig.getSiteCode(),
        maintainConfig.getEquipmentCode(), maintainConfig.getStrategyCode());
    if (c.getStrategyTypeECode().equals(StrategyType.CYCLE.getValue())) {
      if (!maintainConfig.getPrevMaintainDate().equals(c.getPrevMaintainDate())) {
        maintainTaskService.deleteMaintainTaskByStatus(maintainConfig.getSiteCode(), maintainConfig.getEquipmentCode(),
            maintainConfig.getStrategyCode(), MaintainTaskStatus.PLAN.getValue());
      }
    } else {
      if (maintainConfig.getCurrCountValue() != c.getCurrCountValue()) {
        maintainTaskService.deleteMaintainTaskByStatus(maintainConfig.getSiteCode(), maintainConfig.getEquipmentCode(),
            maintainConfig.getStrategyCode(), MaintainTaskStatus.PLAN.getValue());
      }
    }
    if (maintainConfig.getPrevMaintainDate() != null) {
      Calendar cld = Calendar.getInstance();
      cld.setTime(maintainConfig.getPrevMaintainDate());
      maintainConfig.setMaintainDayOfMonth(cld.get(Calendar.DAY_OF_MONTH));
    }
    maintainConfigDao.updateMaintainConfig(maintainConfig);

  }

  @Override
  public BatchJobReport deleteMaintainConfig(String siteCode, String equipmentCode, String strategyCode) {
    String cause = "";
    Boolean success = true;
    try {
      //删除未执行的任务
      maintainTaskService.deleteMaintainTaskByStatus(siteCode, equipmentCode, strategyCode,
          MaintainTaskStatus.PLAN.getValue());
      // 删除系统附件
      List<MaintainConfigAttach> attchs = maintainConfigDao.selectMaintainConfigAttachList(siteCode, equipmentCode,
          strategyCode);
      // 删除业务附件
      maintainConfigDao.deleteMaintainConfigAttachByConfig(siteCode, equipmentCode, strategyCode);
      if (attchs != null && attchs.size() > 0) {
        for (MaintainConfigAttach configAtt : attchs) {
          attachmentService.deleteAttachment(siteCode, configAtt.getAttachmentCode());
        }
      }
      // 删除配置信息
      maintainConfigDao.deleteMaintainConfig(siteCode, equipmentCode, strategyCode);
    } catch (Exception e) {
      LOGGER.error("{}", e);
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      if (DatabaseUtils.isConstraintsError(e.getMessage())) {
        // 外键删除已存在提示
        cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
            SecurityContextUtil.getLanguageCode(), "dataBaseOperationPkFail.M")
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "notDelete.M");
      } else {
        cause = e.getMessage();
      }
      success = false;
    }
    return new BatchJobReport(equipmentCode + "," + strategyCode, cause, success);
  }

  @Override
  public void insertMaintainConfigAttach(MaintainConfigAttach maintainConfigAttach, MultipartFile file) {
    String saveName = UUID.randomUUID().toString();
    String filePath = SkyFileUtils.buildFilePath("maintainConfig");
    String fileName = file.getOriginalFilename();
    String md5 = "";
    try {
      md5 = SkyFileUtils.getMD5String(file.getBytes());
    } catch (IOException e) {
      LOGGER.error("{}", e);
    }
    Attachment att = attachmentService.selectAttachmentByHashCode(maintainConfigAttach.getSiteCode(), md5);
    if (att != null) {
      att.setRefCount(att.getRefCount() + 1);
      attachmentService.updateAttachmentRefCount(att);
      maintainConfigAttach.setAttachmentCode(att.getAttachmentCode());
    } else {
      Long size = file.getSize();
      String newFileName = SkyFileUtils.renameFileName(fileName, saveName);
      FTPUtils ftpUtils = (FTPUtils) SpringBeanUtil.getBean("ftpUtils");
      String savePath = ftpUtils.uploadMultipartFiles(file, filePath, newFileName);
      Attachment atachment = new Attachment();
      atachment.setSiteCode(maintainConfigAttach.getSiteCode());
      atachment.setAttachmentCode(saveName);
      atachment.setSavePath(savePath);
      atachment.setFileName(fileName);
      atachment.setFileSize(size);
      atachment.setHashCode(md5);
      atachment.setRefCount(1);
      attachmentService.insertAttachment(atachment);
      maintainConfigAttach.setAttachmentCode(saveName);
    }

    maintainConfigAttach.setFileName(fileName);
    maintainConfigDao.insertMaintainConfigAttach(maintainConfigAttach);

  }

  @Override
  public MaintainConfigAttach selectMaintainConfigAttach(String siteCode, String equipmentCode, String strategyCode,
      String attachmentCode) {
    return maintainConfigDao.selectMaintainConfigAttach(siteCode, equipmentCode, strategyCode, attachmentCode);
  }

  @Override
  public void deleteMaintainConfigAttach(String siteCode, String equipmentCode, String strategyCode,
      String attachmentCode, String id) {
    maintainConfigDao.deleteMaintainConfigAttach(id);
    attachmentService.deleteAttachment(siteCode, attachmentCode);
  }

  @Override
  public List<MaintainConfig> selectMaintainConfigByStrategyType(String strategyTypeECode) {
    return maintainConfigDao.selectMaintainConfigByStrategyType(strategyTypeECode);
  }

  @Override
  public void updateMaintainConfigUsedByTask(MaintainConfig maintainConfig) {
    maintainConfigDao.updateMaintainConfig(maintainConfig);
  }

  @Override
  public void updatePrevMaintainDate(MaintainConfig maintainConfig) {
    maintainConfigDao.updatePrevMaintainDate(maintainConfig);

  }

}
